<?php
/**
  * @see module.php
  */
extension('sandbox');

define('TEMPLATE_SANDBOX', true);
define('TEMPLATE_TPL_TOKEN', '\s* (?<token> (?=\S) (?: [\s\w\d,.;*/+\-^%$>=]+ | \{(?:(?&token)|[|&]+)*\} | \((?:(?&token)|[|&]+)*\) | \[(?:(?&token)|[|&]+)*\] | (["\'])(?:\\\g-1|.)*?\g-1 )+ | )');

function template($path) {
	$args = func_get_args();

	// Calls `esanum_template_path` or `template_path`
	$path = $args[0] = preprocess('template_path', $path);

	$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
	$function = "_template_$extension";
	if (!$extension || !function_exists($function)) return $path;
	return call_user_func_array($function, $args);
}
function _template_php($path) {
	return $path;
}
function _template_htm($path) {
	return _template_html($path);
}
function _template_html($path) {
	$tmp = sys_get_temp_dir()."/htdocs/$_SERVER[SERVER_NAME]/".localpath($path).'.php';
	$path = serverpath($path);
	if (filemtime($path) >= filemtime($tmp)) {
		$data = file_get_contents($path);
		$data = preg_replace_callback(
			'~ (?<!\\\) (?<whitespace>^[ \t]+)? (?:
				\{ (?:
					/ (?<end> (?<block> if|foreach|for|switch|while) ) |
					(?<cmd> else ) |
					(?: (?<struct> (?&block)|elseif ) \s )?
					'.TEMPLATE_TPL_TOKEN.'
					(?<suffix> (?: \| \w+ (?::(?&token))* )* )
				) \} |
				(?<var>\$\w+(?:->\w+|\[\w+\])*)
			) ~xm',
			'_template_html_var', $data);
		if (TEMPLATE_SANDBOX) $data = sandbox($data);
		if (!file_exists(dirname($tmp))) mkdir(dirname($tmp), 0777, true);
		file_put_contents($tmp, $data);
	}
	return $tmp;
}
function _template_html_var(&$match) {
	static $tag;
	if (!isset($tag)) $tag = ini_get('short_open_tag') ? '<?=' : '<? echo ';
	if ($match['cmd']) return "<?php $match[cmd]:?>";
	if ($match['end']) return "<?php end$match[end]?>";
	if ($match['var']) {
		$code = preg_replace('~(?<=\[)\w+(?=\])~', "'$0'", $match['var']);
	} else {
		$code = trim($match['token']);
		if ($match['suffix']) {
			if (!$code) $code = 'NULL';
			$suffix = $match['suffix'];
			while(preg_match('~^\|\w+~', $suffix, $match)) {
				$func = substr($match[0], 1);
				$suffix = substr($suffix, strlen($match[0]));
				$args = array($code);
				while (preg_match('~^\:'.TEMPLATE_TPL_TOKEN.'~x', $suffix, $match)) {
					$token = trim($match['token']);
					$suffix = substr($suffix, strlen($match[0]));
					$args[] = $token ? $token : 'NULL';
				}
				$code = "$func(".implode(', ', $args).')';
			}
		}
		if ($match['struct']) return "<?php $match[struct]($code):?>";
	}
	if ($match['whitespace']) $code = "str_replace(\"\\n\", \"\\n$match[whitespace]\", $code)";
	return $match['whitespace'].($code ? "$tag$code?>" : '');
}
